package com.seadragon.app.ksr.dao.jpa;

import java.util.List;

import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import org.springframework.stereotype.Repository;

import com.seadragon.app.ksr.dao.CustomerEventSubscriptionDao;
import com.seadragon.app.ksr.model.Customer;
import com.seadragon.app.ksr.model.CustomerEventSubscription;
import com.seadragon.app.ksr.model.Event;
import com.seadragon.app.ksr.model.EventSchedule;

@Repository("customerEventSubscriptionDao")
public class CustomerEventSubscriptionDaoJpaImpl extends AbstractJpaDao implements CustomerEventSubscriptionDao {

	@Override
	public void save(CustomerEventSubscription customerEventSubscription) {
		entityManager.persist(customerEventSubscription);
	}

	@Override
	public List<Customer> findAllSubscribers(Event event) {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<Customer> cq = cb.createQuery(Customer.class);
		Root<CustomerEventSubscription> root = cq.from(CustomerEventSubscription.class);
		cq.select(root.<Customer>get("customer"));
		cq.where(cb.equal(root.<EventSchedule>get("eventSchedule").<Event>get("event"), event));
		List<Customer> customers = entityManager.createQuery(cq).getResultList();
		return customers;
	}

	@Override
	public List<CustomerEventSubscription> findAllSubscriptions(Customer customer) {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<CustomerEventSubscription> cq = cb.createQuery(CustomerEventSubscription.class);
		Root<CustomerEventSubscription> root = cq.from(CustomerEventSubscription.class);
		cq.select(root).where(cb.equal(root.<Customer>get("customer"), customer));
		List<CustomerEventSubscription> customerEventSubscriptions = entityManager.createQuery(cq).getResultList();
		return customerEventSubscriptions;
	}

	@Override
	public List<CustomerEventSubscription> findBy(Customer customer, Event event) {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<CustomerEventSubscription> cq = cb.createQuery(CustomerEventSubscription.class);
		Root<CustomerEventSubscription> root = cq.from(CustomerEventSubscription.class);
		cq.select(root);
		cq.where(cb.and(cb.equal(root.<Customer>get("customer"), customer), cb.equal(root.<EventSchedule>get("eventSchedule").<Event>get("event"), event)));
		List<CustomerEventSubscription> subscriptions = entityManager.createQuery(cq).getResultList();
		return subscriptions;
	}

	@Override
	public List<Customer> findAllSubscribers(Event event, int offset, int pageSize) {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<Customer> cq = cb.createQuery(Customer.class);
		Root<CustomerEventSubscription> root = cq.from(CustomerEventSubscription.class);
		cq.select(root.<Customer>get("customer"));
		cq.where(cb.equal(root.<EventSchedule>get("eventSchedule").<Event>get("event"), event));
		TypedQuery<Customer> tq = entityManager.createQuery(cq);
		tq.setFirstResult(offset);
		tq.setMaxResults(pageSize);
		return tq.getResultList();
	}

	@Override
	public List<CustomerEventSubscription> findAllSubscriptions(Customer customer, int offset, int pageSize) {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<CustomerEventSubscription> cq = cb.createQuery(CustomerEventSubscription.class);
		Root<CustomerEventSubscription> root = cq.from(CustomerEventSubscription.class);
		cq.select(root).where(cb.equal(root.<Customer>get("customer"), customer));
		TypedQuery<CustomerEventSubscription> tq = entityManager.createQuery(cq);
		tq.setFirstResult(offset);
		tq.setMaxResults(pageSize);
		return tq.getResultList();
	}

	@Override
	public void update(CustomerEventSubscription customerEventSubscription) {
		entityManager.merge(customerEventSubscription);
	}

	@Override
	public void delete(CustomerEventSubscription customerEventSubscription) {
		if(entityManager.contains(customerEventSubscription)){
			entityManager.remove(customerEventSubscription);
		}else{
			CustomerEventSubscription ces = entityManager.find(CustomerEventSubscription.class, customerEventSubscription.getId());
			entityManager.remove(ces);
		}
	}

	@Override
	public CustomerEventSubscription findById(long id) {
		return entityManager.find(CustomerEventSubscription.class, id);
	}

}
